'use strict';

const fs = require('fs');
const path = require('path');
const hash = require('./utils/hash');
const validate = require('./utils/validators').validate;

const TEMPLATE_PATH = path.join(__dirname, 'templates');

function buildMainTemplate(config) {
  const template = config.template || path.join(TEMPLATE_PATH, 'main.js');
  return fs.readFileSync(template, 'utf-8');
}

function buildCacheTemplate(config) {
  if (!config.cache) {
    return '';
  }
  const template = config.cache.template || path.join(TEMPLATE_PATH, 'cache.js');
  return fs.readFileSync(template, 'utf-8');
}

function buildNotificationsTemplate(config) {
  if (!config.notifications) {
    return '';
  }
  const template = config.notifications.template || path.join(TEMPLATE_PATH, 'notifications.js');
  return fs.readFileSync(template, 'utf-8');
}

function buildServiceWorker(config) {
  const Cache = config.cache ? JSON.stringify(config.cache, null, 2) : 'undefined';
  const Notifications = config.notifications ? JSON.stringify(config.notifications, null, 2) : 'undefined';
  const Log = config.log ? JSON.stringify(config.log, null, 2) : '{}';
  return [
    '/*\n * AUTOGENERATED FROM GENERATE-SERVICE-WORKER\n */\n',
    `const $VERSION = '${hash(config)}';`,
    `const $DEBUG = ${config.debug || false};`,
    `const $Cache = ${Cache};`,
    `const $Notifications = ${Notifications};`,
    `const $Log = ${Log};\n`,
    buildMainTemplate(config),
    buildCacheTemplate(config),
    buildNotificationsTemplate(config)
  ].join('\n');
}

/*
 * Public API. This method will generate a root service worker and any number of
 * extended configuration service workers (used for testing/experimentation).
 * @returns Object { [key]: service-worker }
 */
module.exports = function generateServiceWorkers(baseConfig, experimentConfigs) {
  validate(baseConfig);

  const serviceWorkers = {
    main: buildServiceWorker(baseConfig)
  };

  Object.keys(experimentConfigs || {}).forEach(key => {
    validate(experimentConfigs[key]);
    serviceWorkers[key] = buildServiceWorker(experimentConfigs[key]);
  });

  return serviceWorkers;
};
